home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MYIO.ZIP
/
MYSTREAM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-02
|
4KB
|
143 lines
// Mystream.cpp
// Implementation of ios interface classes for Myio
//
// Written by David L. Nugent
//
# include <iostream.h>
# include "Mystream.h"
# if defined(_MSC_VER)
# include <memory.h>
# else
# include <stdlib.h>
# endif
// Mystreambuf constructor
// This simply initialises the base class streambuf
// (it is initially empty with no buffer allocated)
// and register the Myio object
// Note: we _could_ set the stream unbuffered here,
// which is useful for stdio handles, so that the
// streambuf functions overflow() and underflow()
// get called on every character rather than when
// the streambuf buffer is full
Mystreambuf::Mystreambuf (Myio * mPtr)
: streambuf (), mptr(mPtr)
{
// unbuffered(1); // Uncomment to make unbuffered
}
// Mystreambuf()
// Called when streambuf owned buffer is full
// or when stream is flushed
// Our job here is to empty the streambuf
// write buffer and reset the 'put' pointers.
int
Mystreambuf::overflow (int c)
{
int written;
// Handle unbuffered stream
if (unbuffered()) // Handle the simple case first
{
if (c == EOF) // Special case, this only flushes
return 0;
char ch = char(c); // Write the byte directly
written = mptr->write (&ch, 1);
return (written) ? c : EOF;
}
// Handle buffered stream
if (!base()) // Need to allocate a buffer
allocate();
if (base()) // Test for memory allocation error
{
char * ep = base() + (blen() / 2);
if (!pbase()) // Set put pointers if not set up
setp (base(), ep);
int bytes = pptr() - pbase(); // Bytes to write
if (bytes)
{
written = mptr->write (pbase(), bytes);
if (!written)
return EOF;
bytes += written;
if (bytes) // Some is still waiting to be written
memcpy (base(), base() + written, bytes);
}
setp (base() + bytes, ep); // Reset 'put' pointers
return (c == EOF) ? 0 : sputc (c); // Put pending chr in buf
}
return EOF;
}
//
// underflow() indicates that the input queue
// is empty and needs more data
//
int
Mystreambuf::underflow (void)
{
int bytes;
// Handle an unbuffered stream
if (unbuffered())
{
bytes = mptr->read (&_back[1], 1);
if (!bytes)
{
setg (0, 0, 0);
return EOF;
}
setg (_back, _back + 1, _back + 2);
return (unsigned char)_back[1];
}
// Handle a buffered stream
if (!base()) // Need to allocate a buffer
allocate();
if (base())
{
char * gp = base() + blen() / 2;
if (gptr() >= egptr())
{ // Read into the buffer from stream
overflow (); // Flush output in case we need it
bytes = mptr->read (gp + 1, blen() / 2 - 1);
setg (gp, gp + 1, gp + bytes + 1);
}
if (gptr() < egptr()) // Get from buffer
return (unsigned char) *gptr();
}
return EOF;
}
//
// sync() needs to empty both put and get
// buffered. It will do this by calling
// overflow and simply resetting the get
// pointers to their default location.
//
int
Mystreambuf::sync (void)
{
if (!unbuffered())
{
overflow (); // Force output
char * gp = base();
setp (gp, gp + blen() / 2);
gp = base() + blen() / 2;
setg (0, 0, 0);
}
return 0;
}